#ifndef ICONS_H_
#define ICONS_H_

#pragma pack( push )
#pragma pack( 2 )
typedef struct {
  BYTE width;                 // Width, in pixels, of the image
  BYTE height;                // Height, in pixels, of the image
  BYTE color_count;           // Number of colors in image (0 if >=8bpp)
  BYTE reserved;              // Reserved ( must be 0)
  WORD planes;                // Color Planes
  WORD bit_count;             // Bits per pixel
  DWORD bytes_in_res;         // How many bytes in this resource?
  DWORD image_offset;         // Where in the file is this image?
} IconDirEntry;

typedef struct {
  WORD reserved;              // Reserved (must be 0)
  WORD type;                  // Resource Type (1 for icons)
  WORD count;                 // How many images?
  IconDirEntry entries[1];    // An entry for each image (idCount of 'em)
} IconDir;

typedef struct {
  BITMAPINFOHEADER header;    // DIB header
  RGBQUAD colors[1];          // Color table
  BYTE xor[1];                // DIB bits for XOR mask
  BYTE and[1];                // DIB bits for AND mask
} IconImage;

typedef struct {
  BYTE width;                 // Width, in pixels, of the image
  BYTE height;                // Height, in pixels, of the image
  BYTE color_count;           // Number of colors in image (0 if >=8bpp)
  BYTE reserved;              // Reserved
  WORD planes;                // Color Planes
  WORD bit_count;             // Bits per pixel
  DWORD bytes_in_res;         // how many bytes in this resource?
  WORD id;                    // the ID
} GrpIconDirEntry;

typedef struct {
  WORD reserved;              // Reserved (must be 0)
  WORD type;                  // Resource type (1 for icons)
  WORD count;                 // How many images?
  GrpIconDirEntry entries[1]; // The entries for each image
} GrpIconDir;

#pragma pack(pop)

struct IconFileData {
  IconDir dir;
  byte* icon_data;
};

struct IconFileList {
  TCHAR iconfile[MAX_PATH];
  int icon_count;
  IconFileData* icon_data_list;
};

struct IconFile {
  TCHAR exefile[MAX_PATH];
  HMODULE handle;
  int index;
  DWORD datasize;
  byte* data;
};

// Class for extract icon data from file.
class Icons {
private:
  Icons(void) {}
  virtual ~Icons(void) {}

public:
  // Extract icons from exe, ico or dll file.
  // Return IconFileList object.
  static IconFileList ExtractIcons(TCHAR* filename);

  // Extract icons from exe, dll file 
  static IconFile ExtractExeIcon(TCHAR* filename, int index);

  // Icon data extracted by ExtractIcons must be freed by FreeData function.
  static void FreeData(IconFileList& iconlist);

  static void FreeData(IconFile& iconfile);
};

#endif